﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using LIMS.Service;
using Castle.Windsor;
using Castle.Windsor.Configuration.Interpreters;
using LIMS.Entities;
using System.Security.Cryptography;
using Castle.Core.Logging;

namespace LIMS.Shared
{
    public class SharedResource
    {
        public static ILogger GetLogger()
        {
            IWindsorContainer container = new WindsorContainer(new XmlInterpreter("Components.config"));
            return container.Resolve<Castle.Core.Logging.ILogger>();
        }

        public static User gLoggedinUser = new User();
        /// <summary>
        /// Resets user password.
        /// </summary>
        /// <param name="sEmailAddress"></param>
        /// <returns></returns>
        public static bool SendResetPasswordRequest(string sEmailAddress, string sUrl, ref string message)
        {
            ILogger logger = GetLogger();
            IWindsorContainer container = new WindsorContainer(new XmlInterpreter("Components.config"));
            IUserManagementService userService = container.Resolve<IUserManagementService>();



            try
            {
                //See if vaild Email
                if (Resource.IsValidEmail(sEmailAddress))
                {
                    //Get user with this Email address
                    User thisUser = userService.GetUserByEmailAddress(sEmailAddress.Trim());
                    if (thisUser != null)
                    {
                        //Try resetting password
                        if (userService.ResetUserPassword(thisUser, sUrl))
                        {
                            //userService.LogUserActivityLog(thisUser.Id, " Password reset request sent.");
                            message = "Password reset instructions have been sent to your Email address.";
                            return true;
                        }
                        else
                        {
                            message = "Error occured while resetting password.Please contact your administrator.";
                            return false;
                        }
                    }
                    else
                    {
                        message = "No user with given Email address found in system.";
                        return false;
                    }
                }
                return false;
            }
            catch (Exception ex)
            {
                logger.Error("Error occured while password reset request.", ex);
                message = "Error occured while password reset request.";
                return false;
            }
        }


        public static bool ResetUserPassword(string userName, string password, ref string message)
        {
            ILogger logger = GetLogger();
            IWindsorContainer container = new WindsorContainer(new XmlInterpreter("Components.config"));
            IUserManagementService userService = container.Resolve<IUserManagementService>();

            try
            {
                User CurrentUser = null;
                if (userService.GetByName(userName, ref CurrentUser))
                {
                    //Make sure user is available
                    if (CurrentUser != null)
                    {
                        //Encrypt password.
                        CurrentUser.Password = Resource.GenerateSHAPasswordHash(password);
                        //Clear reset hash.
                        CurrentUser.ResetPasswordHash = string.Empty;
                        CurrentUser.ResetPasswordDateTime = DateTime.Now;
                        //Save it.
                        userService.Save(CurrentUser);
                        //userService.LogUserActivityLog(view.CurrentUser.Id, " Password reset by user.");
                        return true;
                    }
                }
                else
                {
                    message = "No user found with given Email address.";
                    logger.Error("User was null in ResetUserPassword");
                }
                return false;
            }

            catch (Exception ex)
            {
                logger.Error("Error occured while password reset request.", ex);
                message = "Error occured while password reset request.";
                return false;

            }

        }



        /// <summary>
        /// Handles query string request
        /// </summary>
        /// <param name="passwordResetHash"></param>
        /// <returns></returns>
        public static bool HandleProbablePasswordResetRequest(string passwordResetHash, ref string userId)
        {

            ILogger logger = GetLogger();
            IWindsorContainer container = new WindsorContainer(new XmlInterpreter("Components.config"));
            IUserManagementService userService = container.Resolve<IUserManagementService>();

            try
            {
                //Gets any user with such HASH
                User oUser = userService.GetUserByPasswordResetHash(passwordResetHash);
                if (oUser != null)
                {
                    //If found, set it as current user.
                    userId = oUser.UserName;
                    return true;
                }
                else
                {
                    //No such user.
                    logger.Debug("No user with password reset hash: " + passwordResetHash);
                    return false;
                }
            }
            catch (Exception ex)
            {
                logger.Error("Error while handling password reset request. ", ex);
                return false;
            }
        }

        /// <summary>
        /// Validates user
        /// </summary>
        /// <param name="sUserID"></param>
        /// <param name="sPassword"></param>
        /// <returns></returns>
        public static bool ValidateUser(string sUserID, string sPassword, string IPAddress, ref User p_User, ref string message)
        {
            ILogger logger = GetLogger();
            IWindsorContainer container = new WindsorContainer(new XmlInterpreter("Components.config"));
            IUserManagementService userService = container.Resolve<IUserManagementService>();
            p_User = null;
            try
            {
                //"::1" is loopback address for ipv6
                IPAddress = IPAddress == "::1" ? "127.0.0.1" : IPAddress;
                bool validUser = false;
                User oUser = null;
                if (userService.GetByName(sUserID, ref oUser))
                {
                    if (oUser != null)
                    {
                        if (oUser.Password.Equals(Resource.GenerateSHAPasswordHash(sPassword)))
                        {
                            p_User = oUser;
                            validUser = true;
                        }

                        if (validUser)
                        {
                            if (!oUser.Status.Trim().Equals("A"))
                            {
                                // userService.LogUserActivityLog(view.CurrentUser.Id, "User account inactive(" + view.CurrentUser.UserName + "). IP Address: " + IPAddress);
                                message = "Your account is not active. Plase contact administrator for activation.";
                                return false;
                            }
                            return true;
                        }
                        message = "Invalid login details (" + sUserID + ")";
                        return false;
                    }
                    else
                    {
                        message = "Invalid login details (" + sUserID + ")";
                        return false;
                    }
                }
                else
                {
                    message = "Critical configuration error occured in application. Please contact your administrator.";
                    return false;
                }
            }
            catch (Exception ex)
            {
                message = "Error occured while validating user, please contact administrator";
                logger.Error("Error occured while validating user.", ex);
                return false;

            }
        }


        public static bool UpdateUser(User oUser)
        {
            ILogger logger = GetLogger();
            IWindsorContainer container = new WindsorContainer(new XmlInterpreter("Components.config"));
            IUserManagementService userService = container.Resolve<IUserManagementService>();
            try
            {
                return userService.Save(oUser);
            }
            catch (Exception ex)
            {
                logger.Error("Error occured while validating user.", ex);
                return false;

            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="oUser"></param>
        /// <returns></returns>
        public static List<Department> GetHODDept(User oUser, bool bAddSelect)
        {
            ILogger logger = GetLogger();
            IWindsorContainer container = new WindsorContainer(new XmlInterpreter("Components.config"));
            IDepartmentManagementService departmentservice = container.Resolve<IDepartmentManagementService>();
            try
            {
                if (bAddSelect)
                {
                    Department ode = new Department();
                    ode.Name = "--Select--";
                    ode.Id = 0;

                    List<Department> oDepartments = departmentservice.GetHODDepartment(oUser);
                    oDepartments.Insert(0, ode);
                    return oDepartments;
                }
                else 
                {
                    return departmentservice.GetHODDepartment(oUser);
                }
            }
            catch (Exception ex)
            {
                logger.Error("Error occured while retrieving HOD.", ex);
                return null;

            }
        }

        public static List<User> GetManager(string sDeptID, int iUserType, bool bAddSelect)
        {
            ILogger logger = GetLogger();
            IWindsorContainer container = new WindsorContainer(new XmlInterpreter("Components.config"));
            IUserManagementService UserService = container.Resolve<IUserManagementService>();
            try
            {
                if (bAddSelect)
                {
                    User oUserTemp = new User();
                    oUserTemp.UserName = "--Select--";
                    oUserTemp.Id = 0;

                    List<User> oUsers = UserService.GetManagerByDept(sDeptID, iUserType);
                    oUsers.Insert(0, oUserTemp);
                    return oUsers;
                }
                else
                {
                    return UserService.GetManagerByDept(sDeptID, iUserType);
                }
            }
            catch (Exception ex)
            {
                logger.Error("Error occured while retrieving Manager.", ex);
                return null;

            }
        }

        public static List<User> GetSupervisor(string sDeptId, int iChiefSupID, int iUserType, bool bAddSelect)
        {
            ILogger logger = GetLogger();
            IWindsorContainer container = new WindsorContainer(new XmlInterpreter("Components.config"));
            IUserManagementService UserService = container.Resolve<IUserManagementService>();
            try
            {
                if (bAddSelect)
                {
                    User oUserTemp = new User();
                    oUserTemp.UserName = "--Select--";
                    oUserTemp.Id = 0;

                    List<User> oUsers = UserService.GetSupervisorByManager(sDeptId, iChiefSupID, iUserType);
                    oUsers.Insert(0, oUserTemp);
                    return oUsers;
                }
                else
                {
                    return UserService.GetSupervisorByManager(sDeptId, iChiefSupID, iUserType);
                }
                
            }
            catch (Exception ex)
            {
                logger.Error("Error occured while retrieving supervisor.", ex);
                return null;

            }
        }
        /// <summary>
        /// Save audit trail
        /// </summary>
        /// <param name="oAuditTrail"></param>
        /// <returns></returns>
        public static bool SaveAuditTrail(AuditTrail oAuditTrail)
        {
            ILogger logger = GetLogger();
            IWindsorContainer container = new WindsorContainer(new XmlInterpreter("Components.config"));
            IAuditTrailService AuditTrailService = container.Resolve<IAuditTrailService>();
            try
            {
                return AuditTrailService.Save(oAuditTrail);
                
            }
            catch (Exception ex)
            {
               // logger.Error("Error occured while retrieving supervisor.", ex);
                return false;

            }
        }


        public static string GetCodedStatus(string StatusValue)
        {
            string status = string.Empty;

            try
            {
                if (StatusValue.ToUpper().Trim().Equals("A"))
                {
                    status = "Active";
                }
                else if (StatusValue.ToUpper().Trim().Equals("D"))
                {
                    status = "Deactive";
                }
            }
            catch (Exception ex)
            {

            }
            return status;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="oUser"></param>
        /// <returns></returns>
        public static List<Site> GetSites(User oUser, bool bAddSelect)
        {
            ILogger logger = GetLogger();
            IWindsorContainer container = new WindsorContainer(new XmlInterpreter("Components.config"));
            ISiteManagementService Siteservice = container.Resolve<ISiteManagementService>();
            try
            {
                if (bAddSelect)
                {
                    Site oSiteTemp = new Site();
                    oSiteTemp.Name = "--Select--";
                    oSiteTemp.Id = 0;

                    List<Site> oSites = Siteservice.GetAllSites();
                    oSites.Insert(0, oSiteTemp);
                    return oSites;
                }
                else
                {
                    return Siteservice.GetAllSites();
                }
            }
            catch (Exception ex)
            {
                logger.Error("Error occured while retrieving sites.", ex);
                return null;

            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="oUser"></param>
        /// <returns></returns>
        public static List<Plant> GetPlants(string sSiteId, bool bAddSelect)
        {
            ILogger logger = GetLogger();
            IWindsorContainer container = new WindsorContainer(new XmlInterpreter("Components.config"));
            IPlantManagementService Plantservice = container.Resolve<IPlantManagementService>();
            try
            {
                if (bAddSelect)
                {
                    Plant oPlantTemp = new Plant();
                    oPlantTemp.Name = "--Select--";
                    oPlantTemp.Id = 0;

                    List<Plant> oPlants = Plantservice.GetPlantsBySite(sSiteId);
                    oPlants.Insert(0, oPlantTemp);
                    return oPlants;
                }
                else
                {
                    return Plantservice.GetPlantsBySite(sSiteId);
                }
            }
            catch (Exception ex)
            {
                logger.Error("Error occured while retrieving sites.", ex);
                return null;

            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="oUser"></param>
        /// <returns></returns>
        public static List<Department> GetDepartmentByPlant(string sPlantId, bool bAddSelect)
        {
            ILogger logger = GetLogger();
            IWindsorContainer container = new WindsorContainer(new XmlInterpreter("Components.config"));
            IDepartmentManagementService departmentservice = container.Resolve<IDepartmentManagementService>();
            try
            {
                if (bAddSelect)
                {
                    Department ode = new Department();
                    ode.Name = "--Select--";
                    ode.Id = 0;

                    List<Department> oDepartments = departmentservice.GetAllDepartmentsByPlantId(sPlantId);
                    oDepartments.Insert(0, ode);
                    return oDepartments;
                }
                else
                {
                    return departmentservice.GetAllDepartmentsByPlantId(sPlantId);
                }
            }
            catch (Exception ex)
            {
                logger.Error("Error occured while retrieving HOD.", ex);
                return null;

            }
        }

        public static UserTypePermission GetUserRights(int iUserTypeId)
        {
            ILogger logger = GetLogger();
            IWindsorContainer container = new WindsorContainer(new XmlInterpreter("Components.config"));
            IUserTypePermissionService userrightservice = container.Resolve<IUserTypePermissionService>();
            try
            {
                return userrightservice.GetAllRightsByUserTypeId(iUserTypeId);
            }
            catch (Exception ex)
            {
                logger.Error("Error occured while retrieving HOD.", ex);
                return null;

            }
        }
    }
}
